/**
 * 
 */
package jvs.vfs.opt.contact;

import java.net.URI;
import java.util.ArrayList;

import jvs.vfs.IFile;
import jvs.vfs.opt.ItemInfo;
import jvs.vfs.opt.ItemListFileImpl;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Log;

/**
 * @author qiangli
 * 
 */
public class CallLogFileImpl extends ItemListFileImpl {
	private static class CallItem extends ItemInfo {
		long date;
		// long duration;
		String name;
		String number;
		String numberLabel;
		// int type;
		//
	}

	private static final int MAX_COUNT = 32; // TODO configurable

	private static final String[] LIST = { "/all", "/incoming", "/missed",
			"/outgoing", "/recent", };
	
	private static ItemInfo[][] lists = new ItemInfo[LIST.length][];
	
	private static final String[] LIST_SEL = {
			null,
			android.provider.CallLog.Calls.TYPE + "="
					+ android.provider.CallLog.Calls.INCOMING_TYPE,
			android.provider.CallLog.Calls.TYPE + "="
					+ android.provider.CallLog.Calls.MISSED_TYPE,
			android.provider.CallLog.Calls.TYPE + "="
					+ android.provider.CallLog.Calls.OUTGOING_TYPE, 
			null, };
	
	private static final int LIST_ALL = 0; // sort by title (name, type, num)

	private static final int LIST_INCOME = 1;

	private static final int LIST_MISS = 2;

	private static final int LIST_OUTGO = 3;

	private static final int LIST_RECENT = 4; // by date desc

	private static final String LOG_TAG = "CallLogFileImpl";

	private static void load(Context ctx, ArrayList<CallItem> list, int idx,
			int max) {
		Resources res = ctx.getResources();
		ContentResolver cr = ctx.getContentResolver();
		String by = android.provider.CallLog.Calls.DATE + " DESC";
		String sel = LIST_SEL[idx];
		Cursor c = cr.query(android.provider.CallLog.Calls.CONTENT_URI, null,
				sel, null, by);
		int idCol = c.getColumnIndex(android.provider.CallLog.Calls._ID);
		int dateCol = c.getColumnIndex(android.provider.CallLog.Calls.DATE);
		// int durCol =
		// c.getColumnIndex(android.provider.CallLog.Calls.DURATION);
		int typeCol = c.getColumnIndex(android.provider.CallLog.Calls.TYPE);
		int nameCol = c
				.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
		int numCol = c.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
		int numLabelCol = c
				.getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_LABEL);
		try {
			if (!c.moveToFirst()) {
				return;
			}
			long sortKey = System.currentTimeMillis();
			int count = 0;
			do {
				String id = c.getString(idCol);
				long date = c.getLong(dateCol);
				// long dur = c.getLong(durCol);
				String name = c.getString(nameCol);
				String num = c.getString(numCol);
				String numLabel = c.getString(numLabelCol);
				int type = c.getInt(typeCol);
				Drawable icon = null;
				switch (type) {
				case android.provider.CallLog.Calls.INCOMING_TYPE:
					icon = res
							.getDrawable(android.R.drawable.sym_call_incoming);
					break;
				case android.provider.CallLog.Calls.MISSED_TYPE:
					icon = res.getDrawable(android.R.drawable.sym_call_missed);
					break;
				case android.provider.CallLog.Calls.OUTGOING_TYPE:
					icon = res
							.getDrawable(android.R.drawable.sym_call_outgoing);
					break;
				}
				CallItem ci = new CallItem();
				ci.index = idx;
				ci.id = id;
				ci.title = formatTitle(name, numLabel, num);
				ci.sortkey = sortKey + "";
				ci.name = name;
				// ci.type = type;
				ci.date = date;
				// ci.duration = dur;
				ci.icon = icon;
				ci.number = num;
				ci.numberLabel = numLabel;
				//
				list.add(ci);

				sortKey++;
				count++;
				if (count > max) {
					break;
				}
			} while (c.moveToNext());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			c.close();
		}
	}

	/**
	 * @param uri
	 */
	public CallLogFileImpl(URI uri) {
		super(uri);
	}

	public CallLogFileImpl(URI pu, ItemInfo ai) {
		super(pu, ai);
	}

	@Override
	public boolean execute() {
		try {
			final CallItem item = (CallItem) info;
			if (item == null) {
				return false;
			}
			//
			Context ctx = (Context) fs.getContext();
			Intent i = ContactUtils.createCallIntent(item.number);
			String ti = makeName(item);
			Intent ci = Intent.createChooser(i, ti);
			ci.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			ctx.startActivity(ci);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	private static String formatTitle(String name, String numLabel, String num) {
		final String SP = " ";
		StringBuilder sb = new StringBuilder();
		if (!TextUtils.isEmpty(name)) {
			sb.append(name);
			sb.append(SP);
		}
		if (!TextUtils.isEmpty(numLabel)) {
			sb.append(numLabel);
			sb.append(SP);
		}
		if (!TextUtils.isEmpty(num)) {
			sb.append(num);
		}
		return sb.toString();
	}

	@Override
	public String getDisplayName() {
		CallItem ci = (CallItem) info;
		if (ci != null) {
			return ci.title;
		}
		return super.getDisplayName();
	}

	@Override
	protected String[] getFolders() {
		return LIST;
	}

	@Override
	public Object getIcon() {
		CallItem item = (CallItem) info;
		if (item != null) {
			return item.icon;
		}
		if (isTop()) {
			return null;
		}
		Context ctx = (Context) fs.getContext();
		Resources res = ctx.getResources();
		Drawable icon = null;
		int idx = matchFolder(path);
		switch (idx) {
		case LIST_INCOME:
			icon = res.getDrawable(android.R.drawable.sym_call_incoming);
			break;
		case LIST_MISS:
			icon = res.getDrawable(android.R.drawable.sym_call_missed);
			break;
		case LIST_OUTGO:
			icon = res.getDrawable(android.R.drawable.sym_call_outgoing);
			break;
		case LIST_ALL:
		case LIST_RECENT:
		default:
			icon = res.getDrawable(android.R.drawable.sym_action_call);
		}
		return icon;
	}

	@Override
	public String getPhoneticName() {
		CallItem ci = (CallItem) info;
		if (ci != null) {
			return makeName(ci);
		}
		return super.getPhoneticName();
	}

	@Override
	public String getSortKey() {
		CallItem ci = (CallItem) info;
		if (ci == null) {
			return super.getSortKey();

		}
		return ci.sortkey;
	}

	@Override
	public long getLastModified() {
		CallItem ci = (CallItem) info;
		if (ci == null) {
			return super.getLastModified();
		}
		return ci.date;
	}

	@Override
	public long getLength() {
		return 0;
	}

	@Override
	protected ItemInfo[] load(Context ctx, int idx) {
		ArrayList<CallItem> cl = new ArrayList<CallItem>();
		int max = (idx == LIST_ALL ? Integer.MAX_VALUE : MAX_COUNT);
		load(ctx, cl, idx, max);
		if (DEBUG) {
			Log.d(LOG_TAG, "loaded: " + cl.size() + " max: " +max);
		}
		ItemInfo[] ia = new ItemInfo[0];
		return (cl.size() == 0 ? ia : cl.toArray(ia));
	}

	/**
	 * 
	 * @param item
	 * @return name or label and number
	 */
	private String makeName(CallItem item) {
		final String SP = " ";
		String name = item.name;
		if (!TextUtils.isEmpty(name)) {
			return name;
		}
		StringBuilder sb = new StringBuilder();
		String numLabel = item.numberLabel;
		if (!TextUtils.isEmpty(numLabel)) {
			sb.append(numLabel);
			sb.append(SP);
		}
		String num = item.number;
		if (!TextUtils.isEmpty(num)) {
			sb.append(num);
		}
		return sb.toString();
	}

	@Override
	protected IFile newInstance(URI pu, ItemInfo ai) {
		return new CallLogFileImpl(pu, ai);
	}

	@Override
	protected ItemInfo[][] lists() {
		return lists;
	}
}
